"use client";

import { Divider } from "@heroui/divider";
import { ChevronLeftIcon, ChevronRightIcon, Loader2 } from "lucide-react";
import { Control } from "react-hook-form";

import { Button } from "@/components/shadcn";
import { Form } from "@/components/ui/form";
import { useCredentialsForm } from "@/hooks/use-credentials-form";
import { getAWSCredentialsTemplateLinks } from "@/lib";
import { ProviderCredentialFields } from "@/lib/provider-credentials/provider-credential-fields";
import { requiresBackButton } from "@/lib/provider-helpers";
import {
  AWSCredentials,
  AWSCredentialsRole,
  AzureCredentials,
  GCPDefaultCredentials,
  GCPServiceAccountKey,
  IacCredentials,
  KubernetesCredentials,
  M365CertificateCredentials,
  M365ClientSecretCredentials,
  MongoDBAtlasCredentials,
  OCICredentials,
  ProviderType,
} from "@/types";

import { ProviderTitleDocs } from "../provider-title-docs";
import { AWSStaticCredentialsForm } from "./select-credentials-type/aws/credentials-type";
import { AWSRoleCredentialsForm } from "./select-credentials-type/aws/credentials-type/aws-role-credentials-form";
import { GCPDefaultCredentialsForm } from "./select-credentials-type/gcp/credentials-type";
import { GCPServiceAccountKeyForm } from "./select-credentials-type/gcp/credentials-type/gcp-service-account-key-form";
import {
  M365CertificateCredentialsForm,
  M365ClientSecretCredentialsForm,
} from "./select-credentials-type/m365";
import { AzureCredentialsForm } from "./via-credentials/azure-credentials-form";
import { GitHubCredentialsForm } from "./via-credentials/github-credentials-form";
import { IacCredentialsForm } from "./via-credentials/iac-credentials-form";
import { KubernetesCredentialsForm } from "./via-credentials/k8s-credentials-form";
import { MongoDBAtlasCredentialsForm } from "./via-credentials/mongodbatlas-credentials-form";
import { OracleCloudCredentialsForm } from "./via-credentials/oraclecloud-credentials-form";

type BaseCredentialsFormProps = {
  providerType: ProviderType;
  providerId: string;
  providerUid?: string;
  onSubmit: (formData: FormData) => Promise<any>;
  successNavigationUrl: string;
  submitButtonText?: string;
  showBackButton?: boolean;
};

export const BaseCredentialsForm = ({
  providerType,
  providerId,
  providerUid,
  onSubmit,
  successNavigationUrl,
  submitButtonText = "Next",
  showBackButton = true,
}: BaseCredentialsFormProps) => {
  const {
    form,
    isLoading,
    handleSubmit,
    handleBackStep,
    searchParamsObj,
    externalId,
  } = useCredentialsForm({
    providerType,
    providerId,
    providerUid,
    onSubmit,
    successNavigationUrl,
  });

  const templateLinks = getAWSCredentialsTemplateLinks(externalId);

  return (
    <Form {...form}>
      <form
        onSubmit={form.handleSubmit(handleSubmit)}
        className="flex flex-col gap-4"
      >
        <input
          type="hidden"
          name={ProviderCredentialFields.PROVIDER_ID}
          value={providerId}
        />
        <input
          type="hidden"
          name={ProviderCredentialFields.PROVIDER_TYPE}
          value={providerType}
        />
        {providerUid && (
          <input
            type="hidden"
            name={ProviderCredentialFields.PROVIDER_UID}
            value={providerUid}
          />
        )}

        <ProviderTitleDocs providerType={providerType} />

        <Divider />

        {providerType === "aws" && searchParamsObj.get("via") === "role" && (
          <AWSRoleCredentialsForm
            control={form.control as unknown as Control<AWSCredentialsRole>}
            setValue={form.setValue as any}
            externalId={externalId}
            templateLinks={templateLinks}
          />
        )}
        {providerType === "aws" && searchParamsObj.get("via") !== "role" && (
          <AWSStaticCredentialsForm
            control={form.control as unknown as Control<AWSCredentials>}
          />
        )}
        {providerType === "azure" && (
          <AzureCredentialsForm
            control={form.control as unknown as Control<AzureCredentials>}
          />
        )}
        {providerType === "m365" &&
          searchParamsObj.get("via") === "app_client_secret" && (
            <M365ClientSecretCredentialsForm
              control={
                form.control as unknown as Control<M365ClientSecretCredentials>
              }
            />
          )}
        {providerType === "m365" &&
          searchParamsObj.get("via") === "app_certificate" && (
            <M365CertificateCredentialsForm
              control={
                form.control as unknown as Control<M365CertificateCredentials>
              }
            />
          )}
        {providerType === "gcp" &&
          searchParamsObj.get("via") === "service-account" && (
            <GCPServiceAccountKeyForm
              control={form.control as unknown as Control<GCPServiceAccountKey>}
            />
          )}
        {providerType === "gcp" &&
          searchParamsObj.get("via") !== "service-account" && (
            <GCPDefaultCredentialsForm
              control={
                form.control as unknown as Control<GCPDefaultCredentials>
              }
            />
          )}
        {providerType === "kubernetes" && (
          <KubernetesCredentialsForm
            control={form.control as unknown as Control<KubernetesCredentials>}
          />
        )}
        {providerType === "github" && (
          <GitHubCredentialsForm
            control={form.control}
            credentialsType={searchParamsObj.get("via") || undefined}
          />
        )}
        {providerType === "iac" && (
          <IacCredentialsForm
            control={form.control as unknown as Control<IacCredentials>}
          />
        )}
        {providerType === "oraclecloud" && (
          <OracleCloudCredentialsForm
            control={form.control as unknown as Control<OCICredentials>}
          />
        )}
        {providerType === "mongodbatlas" && (
          <MongoDBAtlasCredentialsForm
            control={
              form.control as unknown as Control<MongoDBAtlasCredentials>
            }
          />
        )}

        <div className="flex w-full justify-end gap-4">
          {showBackButton && requiresBackButton(searchParamsObj.get("via")) && (
            <Button
              type="button"
              variant="ghost"
              size="lg"
              onClick={handleBackStep}
              disabled={isLoading}
            >
              {!isLoading && <ChevronLeftIcon size={24} />}
              Back
            </Button>
          )}
          <Button
            type="submit"
            variant="default"
            size="lg"
            disabled={isLoading}
          >
            {isLoading ? (
              <Loader2 className="animate-spin" />
            ) : (
              <ChevronRightIcon size={24} />
            )}
            {isLoading ? "Loading" : submitButtonText}
          </Button>
        </div>
      </form>
    </Form>
  );
};
